/**
 * 统一错误处理示例
 * 展示如何在API中使用新的错误处理系统
 */

import { ApiCall } from "tsrpc";
import { HandleApiErrors, HandleErrors } from "../../infrastructure/error/ErrorHandlingInitializer";
import { ErrorFactory, GameError } from "../../infrastructure/error/ErrorTypes";
import { createServiceErrorHandler } from "../../infrastructure/error/ErrorHandlingInitializer";
import player from "../../core/rpg/entity/player";
import { ComType } from "../../core/tool/component";
import bag_component from "../../component/bag_component";

// 请求和响应接口示例
interface ReqExampleApi {
    playerId: string;
    itemName: string;
    count: number;
    _player?: player;
}

interface ResExampleApi {
    success: boolean;
    message: string;
    data?: any;
}

/**
 * 示例服务类 - 展示服务级别的错误处理
 */
export class ExampleService {
    private errorHandler = createServiceErrorHandler('ExampleService');

    /**
     * 示例方法 - 使用装饰器自动处理错误
     */
    @HandleErrors()
    async processItemOperation(playerId: string, itemName: string, count: number): Promise<any> {
        // 验证参数
        if (!playerId) {
            throw ErrorFactory.invalidParameter('playerId', playerId);
        }
        
        if (!itemName || itemName.trim() === '') {
            throw ErrorFactory.invalidParameter('itemName', itemName);
        }
        
        if (count <= 0) {
            throw ErrorFactory.invalidParameter('count', count, {
                metadata: { reason: 'Count must be positive' }
            });
        }
        
        // 模拟业务逻辑
        this.errorHandler.log.info('Processing item operation', {
            playerId,
            itemName,
            count
        });
        
        // 模拟可能的业务错误
        if (itemName === 'forbidden_item') {
            throw ErrorFactory.business(
                'BUSINESS_001',
                'This item is forbidden',
                '该物品已被禁用',
                { userId: playerId, metadata: { itemName } }
            );
        }
        
        return {
            playerId,
            itemName,
            count,
            processedAt: Date.now()
        };
    }

    /**
     * 示例方法 - 手动处理错误
     */
    async manualErrorHandling(playerId: string): Promise<any> {
        try {
            // 模拟可能抛出错误的操作
            const result = await this.riskyOperation(playerId);
            
            this.errorHandler.log.info('Manual error handling successful', { playerId });
            return result;
            
        } catch (error) {
            // 手动处理错误
            const gameError = this.errorHandler.handleError(error, 'manualErrorHandling');
            
            // 根据错误类型决定是否重新抛出
            if (gameError.level === 'FATAL') {
                throw gameError;
            }
            
            // 返回默认值
            this.errorHandler.log.warn('Using fallback value due to error', { playerId, error: gameError.message });
            return { playerId, fallback: true };
        }
    }

    private async riskyOperation(playerId: string): Promise<any> {
        // 模拟随机失败
        if (Math.random() < 0.3) {
            throw new Error(`Random failure for player ${playerId}`);
        }
        
        return { playerId, success: true };
    }
}

/**
 * 示例API处理器 - 传统方式（不推荐）
 */
export async function exampleApiTraditional(call: ApiCall<ReqExampleApi, ResExampleApi>) {
    const errorHandler = createServiceErrorHandler('ExampleAPI');
    
    try {
        // 参数验证
        const user = call.req._player as player;
        if (!user) {
            const error = ErrorFactory.userNotFound('', {
                requestId: 'unknown',
                metadata: { reason: 'User not logged in' }
            });
            const response = errorHandler.handleApiError(error);
            call.succ(response as any);
            return;
        }

        // 获取背包组件
        const bagComponent = user.getComponent(ComType.背包) as bag_component;
        if (!bagComponent) {
            const error = ErrorFactory.serviceUnavailable('BagComponent');
            const response = errorHandler.handleApiError(error);
            call.succ(response as any);
            return;
        }

        // 业务逻辑
        const service = new ExampleService();
        const result = await service.processItemOperation(
            user.id,
            call.req.itemName,
            call.req.count
        );

        // 返回成功响应
        const response = errorHandler.createSuccess(result);
        call.succ(response as any);
        
    } catch (error) {
        // 统一错误处理
        const response = errorHandler.handleApiError(error);
        call.succ(response as any);
    }
}

/**
 * 示例API处理器 - 使用装饰器（推荐）
 */
@HandleApiErrors()
export async function exampleApiWithDecorator(call: ApiCall<ReqExampleApi, ResExampleApi>) {
    const errorHandler = createServiceErrorHandler('ExampleAPIWithDecorator');
    
    // 参数验证
    const user = call.req._player as player;
    if (!user) {
        throw ErrorFactory.userNotFound('', {
            requestId: call.req.playerId,
            metadata: { reason: 'User not logged in' }
        });
    }

    // 获取背包组件
    const bagComponent = user.getComponent(ComType.背包) as bag_component;
    if (!bagComponent) {
        throw ErrorFactory.serviceUnavailable('BagComponent', {
            userId: user.id,
            requestId: call.req.playerId
        });
    }

    // 业务逻辑
    const service = new ExampleService();
    const result = await service.processItemOperation(
        user.id,
        call.req.itemName,
        call.req.count
    );

    errorHandler.log.info('API request completed successfully', {
        userId: user.id,
        itemName: call.req.itemName,
        count: call.req.count
    });

    return result;
}

/**
 * 复杂业务逻辑示例 - 展示不同类型的错误处理
 */
export class ComplexBusinessService {
    private errorHandler = createServiceErrorHandler('ComplexBusinessService');

    /**
     * 复杂的业务流程
     */
    @HandleErrors()
    async complexBusinessFlow(userId: string, operationData: any): Promise<any> {
        const methodLogger = this.errorHandler.log;
        const startTime = Date.now();
        
        try {
            methodLogger.info('Starting complex business flow', { userId, operationData });
            
            // 步骤1：验证用户
            await this.validateUser(userId);
            
            // 步骤2：检查权限
            await this.checkPermissions(userId, operationData);
            
            // 步骤3：执行业务逻辑
            const result = await this.executeBusinessLogic(userId, operationData);
            
            // 步骤4：保存结果
            await this.saveResults(userId, result);
            
            methodLogger.info('Complex business flow completed', {
                userId,
                duration: Date.now() - startTime,
                resultSize: JSON.stringify(result).length
            });
            
            return result;
            
        } catch (error) {
            methodLogger.error('Complex business flow failed', error, {
                userId,
                operationData,
                duration: Date.now() - startTime
            });
            
            // 重新抛出，让装饰器处理
            throw error;
        }
    }

    private async validateUser(userId: string): Promise<void> {
        if (!userId || userId.length < 3) {
            throw ErrorFactory.validation('Invalid user ID format', {
                userId,
                metadata: { reason: 'User ID too short' }
            });
        }
        
        // 模拟用户验证
        if (userId === 'invalid_user') {
            throw ErrorFactory.userNotFound(userId);
        }
    }

    private async checkPermissions(userId: string, operationData: any): Promise<void> {
        // 模拟权限检查
        if (operationData.level === 'admin' && !userId.startsWith('admin_')) {
            throw ErrorFactory.authorization('Insufficient permissions for admin operation', {
                userId,
                metadata: { requiredLevel: 'admin', userLevel: 'normal' }
            });
        }
    }

    private async executeBusinessLogic(userId: string, operationData: any): Promise<any> {
        // 模拟复杂业务逻辑
        await this.delay(100); // 模拟异步操作
        
        if (operationData.shouldFail) {
            throw new Error('Simulated business logic failure');
        }
        
        return {
            userId,
            processed: true,
            timestamp: Date.now(),
            data: operationData
        };
    }

    private async saveResults(userId: string, result: any): Promise<void> {
        // 模拟保存操作
        await this.delay(50);
        
        this.errorHandler.log.debug('Results saved', { userId, resultId: result.timestamp });
    }

    private delay(ms: number): Promise<void> {
        return new Promise(resolve => setTimeout(resolve, ms));
    }
}

/**
 * 错误处理模式展示
 */
export class ErrorHandlingPatterns {
    private errorHandler = createServiceErrorHandler('ErrorHandlingPatterns');

    /**
     * 模式1：快速失败
     */
    async failFastPattern(input: any): Promise<any> {
        // 立即验证并失败
        if (!input) {
            throw ErrorFactory.invalidParameter('input', input);
        }
        
        if (!input.id) {
            throw ErrorFactory.validation('Missing required field: id');
        }
        
        return this.processInput(input);
    }

    /**
     * 模式2：重试机制
     */
    async retryPattern(operation: () => Promise<any>, maxRetries = 3): Promise<any> {
        let lastError: GameError | null = null;
        
        for (let attempt = 1; attempt <= maxRetries; attempt++) {
            try {
                this.errorHandler.log.debug(`Attempt ${attempt}/${maxRetries}`);
                return await operation();
            } catch (error) {
                lastError = this.errorHandler.handleError(error, 'retryPattern');
                
                if (attempt === maxRetries) {
                    this.errorHandler.log.error(`All ${maxRetries} attempts failed`, lastError);
                    throw lastError;
                }
                
                // 指数退避
                const delay = Math.pow(2, attempt) * 1000;
                this.errorHandler.log.warn(`Attempt ${attempt} failed, retrying in ${delay}ms`, { error: lastError.message });
                await new Promise(resolve => setTimeout(resolve, delay));
            }
        }
        
        throw lastError;
    }

    /**
     * 模式3：降级处理
     */
    async fallbackPattern(primaryOperation: () => Promise<any>, fallbackOperation: () => Promise<any>): Promise<any> {
        try {
            return await primaryOperation();
        } catch (error) {
            const gameError = this.errorHandler.handleError(error, 'fallbackPattern');
            
            this.errorHandler.log.warn('Primary operation failed, using fallback', { error: gameError.message });
            
            try {
                return await fallbackOperation();
            } catch (fallbackError) {
                const fallbackGameError = this.errorHandler.handleError(fallbackError, 'fallbackPattern');
                
                // 组合错误信息
                throw new GameError({
                    code: 'SYSTEM_001',
                    message: `Both primary and fallback operations failed`,
                    level: 'ERROR',
                    category: 'SYSTEM',
                    context: {
                        metadata: {
                            primaryError: gameError.message,
                            fallbackError: fallbackGameError.message
                        }
                    },
                    userMessage: '服务暂时不可用，请稍后重试'
                });
            }
        }
    }

    private async processInput(input: any): Promise<any> {
        // 模拟处理
        return { processed: input, timestamp: Date.now() };
    }
}
